feat: render the docs sidebar once per section, version, and language (render-once E)#2039
Conversation
✅ Deploy Preview for gethinode-demo ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
c8682e7 to
f5e0c22
Compare
The sidebar tree is now rendered once per (section, version, language, variant) via partialCached in the new uncached wrapper page/sidebar-cached.html, used by both call sites (page/sidebar.html and docs/all.html). The wrapper canonicalizes the page context to the (versioned) section root, passes the base URL (mod-utils GetBaseURL) and the error-path filename as explicit arguments, and leaves Mode B (level-min >= 2) uncached. The renderer (assets/sidebar.html) no longer reads per-page state: the server stops emitting the active class and the expanded collapse trail, always renders the canonical collapsed state, and the current-group anchor swap is removed (the group title always renders its link). Sidebar-internal icons render as inline SVG through the per-call mode argument of mod-fontawesome v6.1.0, including the external-link cue threaded through the new icon-mode argument of assets/link.html, so no per-page sprite registration happens inside the cached subtree. Active-item highlighting, the expanded trail (aria-current, aria-expanded), and the current-group toggle UX move to the new critical script sidebar-active.js, applied per sidebar instance before first paint. Without JavaScript every sidebar group renders expanded via a no-js fallback rule; critical/js-detect.js swaps the marker class. Requires mod-fontawesome v6.1.0 and mod-utils v6.6.0; the FontAwesome webfonts snapshot bump (upstream 2026-07-15) rides along with the module update. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
f5e0c22 to
87c7564
Compare
|
Rebased onto post-flip main (#2042 merged). Conflict resolutions: sidebar-internal icons keep E's |
|
🎉 This PR is included in version 3.4.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Render-once program — chunk E (HELD for maintainer review)
Part of the Hinode render-once implementation program (design:
gethinode.com
docs/superpowers/specs/2026-07-15-sidebar-render-once-design.md, maintainerdecisions §7-1..5). Reduces ~3,420 sidebar item renders to ~114 (one tree per
section/version/language/variant, ~30×) on the exampleSite docs.
Changes
page/sidebar-cached.html— uncached wrapper: key tuple (section, version, lang,variant), context canonicalized to the (versioned) section root,
baseURLviapartialCached utilities/GetBaseURL.html site(mod-utils v6.6.0),filenameas explicitarg; Mode B (
level-min ≥ 2) stays uncached (§7-3). Rawassets/sidebar.htmlremainscache-free and override-friendly (§7-5). Both call sites switched.
assets/sidebar.htmlpage-independent — no serveractive, canonical collapsed state,current-group anchor swap removed (titles always link),
data-sidebar-navroot hook,data-sidebar-match="prefix", zero Scratch reads inside the cached subtree, internal iconsrender
mode="svg"(mod-fontawesome v6.1.0 per-call arg, §7-4 — no sprite-registrationhazard);
titleCaseexactnow reads the section root (§7-1, documented behavior change).sidebar-active.js— per-instance highlight (offcanvas + desktop),aria-current(a11y improvement), collapse-trail expansion, current-group click intercept(§7-2), no-transition init. Plus
js-detect.js(no-js→js) and a.no-jsSCSS fallback(all groups expanded without JS — strictly better than before). No inline styles/scripts (CSP).
snapshot: 4 woff2 files, byte-verified upstream).
hugo mod tidypruned exampleSite pins(same pruning the daily mod-update applies).
Gate evidence (deliberate-diff slice; own gate per design §1.5)
re-verified by the driver: 1 distinct nav hash across 120 instances, 0 server
active.collapse-show / active-removal / anchor-swap / bundle+CSS hashes / woff2 — zero unclassified.
without navigating,
jsclass swap,.no-jsrule in compiled CSS.pnpm testgreen (incl. eslint on the new JS).Notes for review
§2.2 contract).
🤖 Generated with Claude Code